<html>

<body>

<h1>Calculator</h1>

This basic calculator supports the +, -, *, and / operators.<br />
  <i>Standard operator precedence is observed.</i><br /><br />

Valid Operands:
<ul>
  <li>Integers</li>
  <li>Real Numbers</li>
  <li>Negative Numbers</li>
        <i>e.g. "-5"</i><br />
        <u>Note: "+5" is <b>NOT</b> supported</u>
  <li>Fractional Numbers</li>
        <i>e.g. "0.123", ".123", "124."</i><br />

</ul>
<br />

<form action="calculator.php" method="post">
Expression: <input name="expression" type="text"/>
<input type="submit" />
</form>

<?php

  $expr = $_POST["expression"];

  $error = 0;

  //invalid characters
  $pattern = '/[^0-9\.+\-\*\/\\s]/';
  $error += preg_match($pattern, $expr); 
 

if ($error == 0)
{
  $previous = -1;
  $number = 0;
  $period = false;
  $length = strlen($expr);
  for ($i=0; $i<$length; $i++)
  {
    $n = $expr[$i];
    if ($n = ' ' && ($previous == $number || $period))
    {
       $j = $i+1;
       while ($j < $length && $expr[$j] == ' ')
        $j++;     
       if ($j < ($length) && ($expr[$j] == '.' || is_numeric($expr[$j])))
       {
        $error++;
        break;
       }
       $i = $j;
    }
  }
}


  //get rid of spaces
  $pattern = '/\\s/';
  $replace = '';
  $nSps = preg_replace($pattern, $replace, $expr);

  //get rid of double negatives
  $pattern = '/--/';
  $replace = '+';
  $noNegs = preg_replace($pattern, $replace, $nSps);

//  check for syntax errors

  $number = 0;
  $period = false;
  $operator = 1;
  $negative = 2;
  $previous = -1;

if ($error == 0)
{
  $length = strlen($noNegs);
  for ($i=0; $i<$length; $i++)
  {
    $n = $noNegs[$i];
    if (is_numeric($n))
      $n = '^';
    switch ($n)
    {
      case '^':
       $previous = $number;
       break;
      case '.':
       if ($period)
         $error++;
       else
       { $period = true; if(!(($previous == $number) || (($i != ($length-1)) && (is_numeric($noNegs[$i+1])) ))) $error++;
       }
       break;
       case '-': $period = false; $previous = $negative;
         break;
       case '+':
       case '*':
       case '/':
         $period = false;
         if ($previous == $operator || $i == ($length-1) || $i == 0)
         {
           $error++;
         }
         $previous = $operator;
         break;
    }
  if ($error > 0)
    break;
  }
}


if (isset($_POST['expression']))
{
  if ($error > 0)
    echo "Invalid expression: " . $expr;
  else
  {
    eval("\$result = @($noNegs);");
    echo "Result: " . $expr . " = " . $result;
  }
}

?>

</body>

</html>
